home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / eulisp / feel0_89.lha / Feel / Src / copyalloc.c < prev    next >
C/C++ Source or Header  |  1993-07-12  |  20KB  |  878 lines

  1.  /*    
  2.   * Allocation routines for feel
  3.   *
  4.   */
  5.  
  6. /* what we need to stay ahead*/
  7. #include "defs.h"
  8. #include "structs.h"
  9. #include "funcalls.h"
  10. #include "global.h"
  11. #include "allocate.h" 
  12. #include "error.h"
  13. #include "table.h"
  14. #include "threads.h" 
  15.  
  16. /* other junk */
  17. #include "copy.h"
  18.  
  19. #ifndef DEFAULT_HEAP_SIZE
  20. #define DEFAULT_HEAP_SIZE (4*1024*1024)
  21. #endif
  22.  
  23. #ifndef DEFAULT_STACK_SPACE_SIZE
  24. #define DEFAULT_STACK_SPACE_SIZE (1*1024*1024)
  25. #endif
  26.  
  27. #define N_SLOTS_IN_CLASS N_SLOTS_IN_STRUCT(struct class_structure)
  28. #define N_SLOTS_IN_THREAD N_SLOTS_IN_STRUCT(struct thread_structure)
  29.  
  30. #ifdef ALIGN8
  31. #define ROUNDTO 8
  32. #else
  33. #define ROUNDTO 8
  34. #endif
  35.  
  36. #define ROUND_ADDR(x) ((((int)x)&(ROUNDTO-1))==0 ? x : x+(ROUNDTO-((int)x&(ROUNDTO-1))))
  37.  
  38. #ifdef NODEBUG
  39. #define FPRINTF_GC_BUG(x) 
  40. #define GC_BUG(x)
  41. #else
  42. #define GC_BUG(x) x
  43. #define FPRINTF_GC_BUG(x) fprintf x
  44. #endif
  45.  
  46. LispObject static_ints;
  47. LispObject static_chars;
  48.  
  49. static void initialise_stack_space(int);
  50.  
  51. void runtime_initialise_allocator(LispObject *stacktop)
  52. {
  53.   extern void init_allocator(int);
  54.   extern int command_line_heap_size;
  55.   extern int command_line_stack_space_size;
  56.   extern int command_line_cons_percentage;
  57.   extern int command_line_cons_cut_off;
  58.  
  59.   int heap,stack_space;
  60.   
  61.   heap = (command_line_heap_size == 0
  62.             ? DEFAULT_HEAP_SIZE 
  63.             : command_line_heap_size);
  64.  
  65.   if (heap < 50)
  66.     heap=heap*1024*1024;
  67.  
  68.  
  69.   {
  70.     extern int command_line_cons_percentage;
  71.     extern int command_line_cons_cut_off;
  72.     
  73.     if (command_line_stack_space_size < 50)
  74.       command_line_stack_space_size = command_line_stack_space_size*1024*1024;
  75.  
  76.     stack_space = (command_line_stack_space_size == 0
  77.            ? DEFAULT_STACK_SPACE_SIZE
  78.            : command_line_stack_space_size);
  79.   }
  80.  
  81.   init_allocator(heap); /* ifdef CGC this does nothing */
  82.   initialise_stack_space(stack_space); /* and this calls gc_init() */
  83.  
  84.   /* so if CGC is defined, all the above does is call gc_init() */
  85.  
  86.   /* Really need a smarter way of doing these... --- like do them last */
  87.   add_root(&state_dynamic_env);
  88.   add_root(&state_last_continue);
  89.   add_root(&state_handler_stack);
  90.   add_root(&state_current_thread);
  91. }
  92.  
  93. char *allocate_space(LispObject *stacktop,int n)
  94. {
  95.   char* allocate_stack(LispObject *stacktop, int nbytes);  
  96.  
  97.   return allocate_stack(stacktop,n);
  98. }
  99.  
  100. void deallocate_space(LispObject*stacktop,char *addr,int siz)
  101. {
  102.   void deallocate_stack(LispObject *, char *, int);
  103.  
  104.   deallocate_stack(stacktop,addr,siz);
  105. }
  106. void runtime_initialise_collector(LispObject *stacktop)
  107. {
  108.  
  109. }
  110.  
  111. #define NOT_YET_DONE(name) \
  112. { fprintf(stderr,"%s: cannot alloc\n",name) ; return nil;}
  113.   
  114. LispObject Fn_cons(LispObject *stacktop)
  115. {
  116.   LispObject ans;
  117.  
  118.   ans = allocate_nbytes(stacktop+2,sizeof(struct cons_structure),TYPE_CONS); 
  119.   
  120.   lval_classof(ans)=Cons;
  121.   ans->CONS.car= *stacktop;
  122.   ans->CONS.cdr= *(stacktop+1);
  123.   
  124.   return ans;
  125. }
  126.  
  127. /* Optimised to allow easier code in a lot of places... */
  128. LispObject allocate_n_conses(LispObject *stacktop, int n)
  129. {    
  130.   LispObject xx;
  131.   int i;
  132. #if 1
  133. #ifdef DGC 
  134. Dunc --- this wont work with your stuff, right?
  135. #endif
  136.   LispObject tmp,prev;
  137.   struct cons_structure *ptr;
  138.  
  139.   xx=allocate_nbytes(stacktop,n*sizeof(struct cons_structure),TYPE_CONS);
  140.   ptr=&(xx->CONS);
  141.   prev=nil;
  142.  
  143.   for (i=0; i< n; i++)
  144.     {
  145.       tmp=(LispObject) ptr;
  146.       lval_typeof(tmp)=TYPE_CONS;
  147.       gcof(tmp)=current_space();
  148. #ifdef GENERATIONAL
  149.       ageof(tmp)=0;
  150. #endif
  151.       lval_classof(tmp)=Cons;
  152.       CAR(tmp)=nil;
  153.       CDR(tmp)=prev;
  154.       
  155.       prev=tmp;
  156.       ptr++;
  157.     }
  158.   
  159.   return (LispObject) tmp;
  160. #else
  161.   xx=nil;
  162.   for (i=0; i<n; i++)
  163.     {
  164.       xx=EUCALL_2(Fn_cons,nil,xx);
  165.     }
  166.       
  167.   return xx;
  168.  
  169. #endif
  170. }
  171.  
  172. LispObject allocate_n_envs(LispObject *stacktop, int n, LispObject last)
  173. {    
  174.   LispObject xx;
  175.   int i;
  176.   xx=last;
  177.   for (i=0; i< n; i++)
  178.     {
  179.       xx=allocate_env(stacktop,nil,nil,xx);
  180.     }
  181.  
  182.   return xx;
  183. }
  184.  
  185. LispObject allocate_class(LispObject *stacktop,LispObject class)
  186. {    /* Really the same as allocate_integer, but we have to be a 
  187.      * little careful at bootstrap */
  188.   LispObject ans;
  189.   int i;
  190.  
  191.   STACK_TMP(class);
  192.   if (class==NULL)
  193.     ans = allocate_nbytes(stacktop,sizeof(struct class_structure),TYPE_CLASS);
  194.   else 
  195.     ans = allocate_nbytes(stacktop,
  196.               sizeof(Object_t)+sizeof(LispObject)*intval(class->CLASS.local_count),
  197.               TYPE_CLASS);
  198.   UNSTACK_TMP(class);
  199.   lval_classof(ans) = class==NULL ? nil : class;
  200.  
  201.   (ans->CLASS).local_count = (class==NULL) ? nil : allocate_integer(stacktop,0);
  202.   (ans->CLASS).name = unbound;
  203.   (ans->CLASS).superclasses = nil;
  204.   (ans->CLASS).subclasses = nil;
  205.   (ans->CLASS).local_slot_list = nil;
  206.   (ans->CLASS).slot_list = nil;
  207.   (ans->CLASS).nonlocal_slot_list = nil;
  208.   (ans->CLASS).precedence = nil;
  209.   (ans->CLASS).spare1 = nil;
  210.   (ans->CLASS).spare2 = nil;
  211.   
  212.   if (class!=NULL)
  213.     {
  214.       for (i=N_SLOTS_IN_CLASS ; i<intval(class->CLASS.local_count) ; i++)
  215.     slotref(ans,i) = nil;
  216.     }
  217.   return ans;
  218. }
  219.  
  220. LispObject allocate_instance(LispObject *stacktop,LispObject class)
  221. {
  222.   LispObject ans;
  223.   int i;
  224.  
  225.   STACK_TMP(class);
  226.  
  227.   ans=allocate_nbytes(stacktop,sizeof(Object_t)
  228.               +sizeof(LispObject)*intval(class->CLASS.local_count),TYPE_INSTANCE);
  229.  
  230.   UNSTACK_TMP(class);
  231.   lval_classof(ans)=class;
  232.  
  233.   for (i=0; i<intval(class->CLASS.local_count); i++)
  234.     slotref(ans,i)=unbound;
  235.  
  236.   return ans;
  237. }
  238.  
  239. LispObject allocate_thread(LispObject *stacktop,int stack_size, 
  240.                int gc_stack_size, int nslots)
  241.   char* allocate_stack(LispObject *stacktop, int nbytes);
  242.   /* xxx: need extra slots hack */
  243.   LispObject ans,cont,data;
  244.   int extra;
  245.  
  246.   extra=nslots>0? nslots-N_SLOTS_IN_THREAD: 0;
  247.   cont = allocate_continue(stacktop);
  248.   STACK_TMP(cont);
  249.   data = allocate_string(stacktop,"",sizeof(struct thread_data));
  250.   memset(stringof(data),sizeof(struct thread_data), 0);
  251.  
  252.   STACK_TMP(data);
  253.  
  254.   ans=allocate_nbytes(stacktop,
  255.               sizeof(struct thread_structure)+extra*sizeof(LispObject),
  256.               TYPE_THREAD);
  257.  
  258.   lval_classof(ans) = Thread;
  259.   UNSTACK_TMP(data);
  260.   ans->THREAD.sysdata = data;
  261.   thread_stack_size(ans)=stack_size;
  262.   thread_gc_stack_size(ans) = gc_stack_size;
  263.  
  264.   ans->THREAD.fun = nil;
  265.   ans->THREAD.args = nil;
  266.   ans->THREAD.value = nil;
  267.  
  268.   thread_status(ans) = 0;
  269.  
  270.   ans->THREAD.thd_queue = nil;
  271.  
  272.   UNSTACK_TMP(cont);
  273.   ans->THREAD.state = cont;
  274.   thread_stack_base(ans) = NULL;
  275.   thread_gc_stack_base(ans) = NULL;
  276.  
  277.   ans->THREAD.state->CONTINUE.thread=ans;
  278.  
  279. #ifdef MACHINE_ANY
  280.  
  281.   thread_stack_base(ans) = (int *) allocate_stack(stacktop+1,stack_size);
  282.   (ans->THREAD.state)->CONTINUE.gc_stack_pointer =
  283.     thread_gc_stack_base(ans) =
  284.       (LispObject *) allocate_stack(stacktop+1,gc_stack_size*sizeof(LispObject));
  285.   
  286.   STACK_TMP(ans);
  287.   cont=EUCALL_2(Fn_cons,function_default_handler,nil);
  288.   UNSTACK_TMP(ans);
  289.   ans->THREAD.state->CONTINUE.handler_stack = cont;
  290.     
  291. #else
  292.  
  293.   thread_stack_base(ans) = NULL;
  294.   thread_gc_stack_base(ans) = NULL;
  295.   ans->THREAD.state->CONTINUE.gc_stack_pointer = NULL;
  296.   STACK_TMP(ans);
  297.   cont =  EUCALL_2(Fn_cons,function_default_handler,nil);
  298.   UNSTACK_TMP(ans);
  299.   ans->THREAD.state->CONTINUE.handler_stack = cont;
  300.  
  301.   ans->THREAD.sig_queue=nil;
  302. #endif
  303.   { /* ugh */
  304.     int i;
  305.     if (extra>0)
  306.       for(i=N_SLOTS_IN_THREAD; i<nslots; i++)
  307.     slotref(ans,i) = unbound;
  308.   }
  309.   return ans;
  310. }
  311.  
  312. LispObject allocate_vector(LispObject *stacktop,int size)
  313. {
  314.   LispObject ans;
  315.   int i;
  316.  
  317.   ans = allocate_nbytes(stacktop,sizeof(Object_t)+sizeof(int)+size*sizeof(LispObject),
  318.             TYPE_VECTOR);
  319.   
  320.   lval_classof(ans)= Vector;
  321.   
  322.   ans->VECTOR.length=size;
  323.  
  324.   for(i=0; i<size ; i++)
  325.     vref(ans,i)=nil;
  326.  
  327.   return ans;
  328. }
  329.  
  330. LispObject allocate_string(LispObject *stacktop, char *string, int len)
  331. {
  332.   LispObject ans;
  333.  
  334.   len++;
  335.   len=ROUND_ADDR(len);
  336.   ans = allocate_nbytes(stacktop,sizeof(Object_t)+sizeof(int)+len,
  337.             TYPE_STRING); 
  338.   
  339.   lval_classof(ans)=String;
  340.   ans->STRING.length= len;
  341.   stringof(ans)[len-1]=0;
  342.   strncpy(stringof(ans),string,len);
  343.  
  344.   return ans;
  345. }
  346.  
  347. LispObject allocate_symbol(LispObject *stacktop, char *str)
  348. {
  349.   int hash(char *); /* from tables.c */
  350.   extern int command_line_processors; /* yuck! */
  351.  
  352.   int hv;
  353.   LispObject ans;
  354.   LispObject tmp,tmp2;
  355.   
  356.   tmp=allocate_string(stacktop,str,strlen(str));
  357.   STACK_TMP(tmp);
  358.   hv=hash(str);
  359.   ans=allocate_nbytes(stacktop,sizeof(struct symbol_structure),TYPE_SYMBOL);
  360.   UNSTACK_TMP(tmp);
  361.  
  362.   lval_classof(ans)=Symbol;
  363.   ans->SYMBOL.pname=tmp;
  364. #ifdef MACHINE_SYSTEMV
  365.   STACK_TMP(ans);
  366.   tmp=allocate_vector(stacktop,command_line_processors);
  367.   STACK_TMP(tmp);
  368.   tmp2=allocate_vector(stacktop,command_line_processors);
  369.   UNSTACK_TMP(tmp);
  370.   UNSTACK_TMP(ans);
  371.   ans->SYMBOL.lmodule=tmp;
  372.   ans->SYMBOL.lvalue=tmp2;
  373. #else
  374.   ans->SYMBOL.lmodule=nil;
  375.   ans->SYMBOL.lvalue=nil;
  376. #endif
  377.   ans->SYMBOL.gvalue = NULL;
  378.   ans->SYMBOL.left = NULL;
  379.   ans->SYMBOL.right = NULL;
  380.   ans->SYMBOL.hash = hv;
  381.  
  382.   return ans;
  383. }
  384.  
  385. LispObject allocate_module_function(LispObject *stacktop,
  386.                     LispObject mod,LispObject name,
  387.                     LispObject (*fun)(LispObject*),
  388.                     int code)
  389. {
  390.   LispObject ans;
  391.  
  392.   STACK_TMP(name); STACK_TMP(mod);
  393.   ans=allocate_nbytes(stacktop,sizeof(struct c_function_structure),TYPE_C_FUNCTION);
  394.   UNSTACK_TMP(mod); UNSTACK_TMP(name);
  395.   lval_classof(ans) = CFunction;
  396.  
  397.   ans->C_FUNCTION.name = name;
  398.   ans->C_FUNCTION.home = mod;
  399.   ans->C_FUNCTION.argtype = code;
  400.   ans->C_FUNCTION.env = NULL;
  401.   ans->C_FUNCTION.setter = nil;
  402.  
  403.   ans->C_FUNCTION.func = fun;
  404.   
  405.   return ans;
  406. }
  407.  
  408. #ifdef NOLOWTAGINTS
  409. LispObject real_allocate_integer(LispObject *stacktop, int n)
  410. {
  411.   LispObject ans;
  412.  
  413.   if (n>=0 && n<STATIC_INTEGERS)
  414.     return vref(static_ints,n);
  415.  
  416.   ans=allocate_nbytes(stacktop,sizeof(struct integer_structure),TYPE_INT);
  417.  
  418.   lval_classof(ans)=Integer;
  419.   intval(ans)=n;
  420.  
  421.   return ans;
  422. }
  423. #endif
  424.  
  425. LispObject allocate_float(LispObject *stacktop,double x )
  426. {
  427.   LispObject ans;
  428.  
  429.   ans=allocate_nbytes(stacktop,sizeof(struct float_structure),TYPE_FLOAT);
  430.  
  431.   lval_classof(ans)=Real;
  432.   ans->FLOAT.fvalue=x;
  433.   
  434.   return ans;
  435.   
  436. }
  437.  
  438. static LispObject real_allocate_char(LispObject *stacktop, int x)
  439. {
  440.   LispObject ans;
  441.  
  442.   ans=allocate_nbytes(stacktop,sizeof(struct character_structure),
  443.               TYPE_CHAR);
  444.   lval_classof(ans)=Character;
  445.   ans->CHAR.font=0;
  446.   ans->CHAR.code=x;
  447.   return ans;
  448.   
  449. }
  450.  
  451. LispObject allocate_char(LispObject *stacktop,int x)
  452. {
  453.   if (x<0 || x>MAX_CHAR)
  454.     return (real_allocate_char(stacktop,x));
  455.   else
  456.     return vref(static_chars,x);
  457. }
  458.  
  459. LispObject allocate_continue(LispObject *stacktop)
  460. {
  461.  
  462.   LispObject ans;
  463.  
  464.   ans=allocate_nbytes(stacktop,sizeof(struct continue_structure),TYPE_CONTINUE);
  465.  
  466.   lval_classof(ans) = Continue;
  467.  
  468.   (ans->CONTINUE).thread = nil;
  469.  
  470.   (ans->CONTINUE).value = nil;
  471.   (ans->CONTINUE).target = nil;
  472.  
  473.   /*  (ans->CONTINUE).machine_state; */
  474.   (ans->CONTINUE).gc_stack_pointer = NULL;
  475.   (ans->CONTINUE).dynamic_env = NULL;
  476.   (ans->CONTINUE).last_continue = nil;
  477.   (ans->CONTINUE).handler_stack = nil;
  478.  
  479.   (ans->CONTINUE).dp = nil;
  480.  
  481.   (ans->CONTINUE).live = FALSE;
  482.   (ans->CONTINUE).unwind = FALSE;  
  483.   
  484.   return ans;
  485. }
  486.  
  487. LispObject allocate_env(LispObject *stacktop, LispObject name, 
  488.             LispObject value, LispObject prev)
  489. {
  490.   LispObject ans;
  491.  
  492.   STACK_TMP(prev); STACK_TMP(name); STACK_TMP(value);
  493.   ans=allocate_nbytes(stacktop,sizeof(struct env_structure),TYPE_ENV);
  494.   UNSTACK_TMP(value); UNSTACK_TMP(name); UNSTACK_TMP(prev);
  495.   lval_classof(ans) = nil; /* ? */
  496.  
  497.   ans->ENV.variable = name;
  498.   ans->ENV.value = value;
  499.   ans->ENV.next = prev;
  500.  
  501.   return ans;
  502. }
  503.  
  504. LispObject allocate_envimut(LispObject *stacktop, LispObject name, LispObject value, LispObject prev)
  505. {
  506.   LispObject ans;
  507.   
  508.   ans=allocate_env(stacktop,name,value,prev);
  509.   
  510.   lval_typeof(ans)=TYPE_FIXENV;
  511.   return ans;
  512. }
  513.  
  514. LispObject allocate_special(LispObject *stacktop, 
  515.                 LispObject name, 
  516.                 LispObject (*fn)(LispObject *))
  517. {
  518.   LispObject ans;
  519.  
  520.   STACK_TMP(name);
  521.   ans=allocate_nbytes(stacktop,sizeof(struct special_structure),TYPE_SPECIAL);
  522.   UNSTACK_TMP(name);
  523.  
  524.   lval_classof(ans) = Object;
  525.  
  526.   ans->SPECIAL.name  = name;
  527.   ans->SPECIAL.env   = NULL;
  528.   ans->SPECIAL.func  = fn;
  529.  
  530.   return(ans);
  531.  
  532. }
  533.  
  534.  
  535. LispObject allocate_i_function(LispObject *stacktop, LispObject mod, 
  536.                    LispObject env, int argcode)
  537. {
  538.   LispObject ans;
  539.  
  540.   STACK_TMP(mod); STACK_TMP(env);
  541.   ans=allocate_nbytes(stacktop,sizeof(struct i_function_structure),TYPE_I_FUNCTION);
  542.  
  543.   UNSTACK_TMP(env); UNSTACK_TMP(mod);
  544.   lval_classof(ans)=IFunction;
  545.   ans->I_FUNCTION.name=nil;
  546.   ans->I_FUNCTION.home = mod;
  547.   ans->I_FUNCTION.env = env;
  548.   ans->I_FUNCTION.argtype = argcode;
  549.   
  550.   ans->I_FUNCTION.bvl = nil;
  551.   ans->I_FUNCTION.body = nil;
  552.  
  553.   return ans;
  554. }
  555.  
  556.  
  557. LispObject allocate_i_module(LispObject *stacktop, LispObject name)
  558. {
  559.   LispObject ans;
  560.  
  561.   STACK_TMP(name);
  562.   ans=allocate_nbytes(stacktop,sizeof(struct i_module_structure), TYPE_I_MODULE);
  563.   UNSTACK_TMP(name);
  564.  
  565.   lval_classof(ans)=Object;
  566.   ans->I_MODULE.name = name;
  567.   ans->I_MODULE.home = nil;
  568.   ans->I_MODULE.exported_names = nil;
  569.   ans->I_MODULE.bounce_flag = nil;
  570.   ans->I_MODULE.imported_modules = nil; /* HACK !!! GC */
  571.   ans->I_MODULE.bindings = nil;
  572.   
  573.   return ans;
  574. }
  575.  
  576. #if (defined(WITH_BSD_SOCKETS) || defined(WITH_SYSTEMV_SOCKETS))
  577.  
  578. LispObject allocate_listener(LispObject *stacktop)
  579. {
  580.   LispObject ans;
  581.  
  582.   ans=allocate_nbytes(stacktop,sizeof(struct listener_structure), TYPE_LISTENER);
  583.   lval_classof(ans)=nil; /* will be set later */
  584.   return ans;
  585. }
  586.  
  587.  
  588. LispObject allocate_socket(LispObject *stacktop)
  589. {
  590.   LispObject ans;
  591.   
  592.   ans=allocate_nbytes(stacktop,sizeof(struct socket_structure), TYPE_SOCKET);
  593.   lval_classof(ans)=nil; /* will be set later */
  594.   return ans;
  595. }
  596. #endif
  597.  
  598. LispObject allocate_semaphore(LispObject *stacktop)
  599. {
  600.   LispObject ans;
  601.   
  602.   ans=allocate_nbytes(stacktop,sizeof(struct semaphore_structure), TYPE_SEMAPHORE);
  603.  
  604.   lval_classof(ans)=Object; /* Ugh */
  605.   system_allocate_semaphore(&(ans->SEMAPHORE.semaphore));
  606.  
  607.   return ans;
  608. }
  609.  
  610. LispObject allocate_static_vector(LispObject *stacktop,int nslots)
  611. {
  612.   LispObject space;
  613.   int i;
  614.  
  615.   space=(LispObject) allocate_space(stacktop,sizeof(Object_t)+sizeof(int)+nslots*sizeof(LispObject));
  616.   
  617.   for (i=0; i<nslots; i++)
  618.     vref(space,i)=NULL;
  619.  
  620.   lval_typeof(space)=TYPE_VECTOR|STATIC_TYPE;
  621.   lval_classof(space)=Vector;
  622.   gcof(space)=current_space();
  623.   ageof(space)=0;
  624.   space->VECTOR.length=nslots;
  625.  
  626.   return(space);
  627. }
  628.  
  629. LispObject allocate_static_string(LispObject *stacktop, int size)
  630. {
  631.   LispObject space;
  632.   size++;
  633.   size=ROUND_ADDR(size);
  634.   space=(LispObject) allocate_space(stacktop,sizeof(Object_t)+sizeof(int)+size);
  635.   
  636.   lval_typeof(space)=TYPE_STRING|STATIC_TYPE;
  637.   lval_classof(space)=String;
  638.   gcof(space)=current_space();
  639.   ageof(space)=0;
  640.   space->STRING.length=size;
  641.   return (space);
  642. }
  643.  
  644.  
  645. void allocate_static_integers(LispObject *stacktop)
  646. {
  647. #ifdef NOLOWTAGINTS
  648.   int i;
  649.  
  650.   static_ints=allocate_static_vector(stacktop,STATIC_INTEGERS);
  651.   for (i=0; i<STATIC_INTEGERS; i++)
  652.     {        /* alloc a big integer, then 'fix' it */
  653.       LispObject xx=real_allocate_integer(stacktop,STATIC_INTEGERS);
  654.       intval(xx)=i;
  655.       vref(static_ints,i)=xx;
  656.     }
  657.  
  658.   add_root(&static_ints);
  659. #endif
  660. }
  661.  
  662. void allocate_static_chars(LispObject *stacktop)
  663. {
  664.   int i;
  665.   static_chars=allocate_static_vector(stacktop,MAX_CHAR+1);
  666.   
  667.   for (i=0; i<MAX_CHAR+1 ; i++)
  668.     {
  669.       LispObject c=real_allocate_char(stacktop,i);
  670.       vref(static_chars,i)=c;
  671.     }
  672.   add_root(&static_chars);
  673. }
  674.  
  675. typedef struct free_list_struct
  676. {
  677.   int size;
  678.   struct free_list_struct *next;
  679. } *FreeList;
  680.  
  681. static SYSTEM_GLOBAL(FreeList, stack_chain);
  682.  
  683. static int free_count;
  684. static int nfrags;
  685.  
  686. #ifdef CGC
  687. static void initialise_stack_space(int stackspace)
  688. {
  689.   gc_init();
  690. }
  691. #else
  692. static void initialise_stack_space(int stackspace)
  693. {
  694.   char *space;
  695.   int allocated=0;
  696.   FreeList *chain_end;
  697.   
  698.   SYSTEM_INITIALISE_GLOBAL(FreeList,stack_chain,NULL);
  699.  
  700.   chain_end=&SYSTEM_GLOBAL_VALUE(stack_chain);
  701.   nfrags=0;
  702.   while (allocated < stackspace)
  703.     {
  704.       int sz;
  705.       
  706.       sz=stackspace-allocated;
  707.       if (sz>SYSTEM_MAX_SHARED_SIZE)
  708.     sz=SYSTEM_MAX_SHARED_SIZE;
  709.  
  710.       space=system_malloc(sz);
  711.  
  712.       *chain_end=(FreeList)space;
  713.  
  714.       (*chain_end)->size= sz - sizeof(*chain_end);
  715.       (*chain_end)->next= NULL;
  716.       chain_end=&((*chain_end)->next);
  717.       free_count+=SYSTEM_GLOBAL_VALUE(stack_chain)->size;
  718.       
  719.       allocated+=sz;
  720.       nfrags++;
  721.     }
  722. }
  723. #endif
  724.  
  725. void show_stack_space()
  726. {
  727.   fprintf(stderr,"Stack space: %d remaining, %d fragments\n",free_count, nfrags);
  728. }
  729.  
  730. /* use header as pointer to prevously allocated stack */
  731.  
  732. #ifdef CGC
  733. char* allocate_stack(LispObject *stacktop, int nbytes)
  734. {
  735.   return (char *)gc_malloc(nbytes);
  736. }
  737. #else
  738. char* allocate_stack(LispObject *stacktop, int nbytes)
  739. {
  740.   FreeList oldstack;
  741.   FreeList *walker;
  742.   char *ret;
  743.  
  744.   if (nbytes==0)
  745.     return NULL;
  746.  
  747.   system_open_semaphore(stacktop,&S_G_V(GC_sem)); 
  748.   walker= &SYSTEM_GLOBAL_VALUE(stack_chain);
  749.   nbytes=ROUND_ADDR(nbytes);
  750.  
  751.   free_count -= nbytes;
  752.  
  753.   while ( (*walker)!=NULL)
  754.     {
  755.       if ((*walker)->size+sizeof(*walker)==nbytes)
  756.     { 
  757.       ret= (char*) (*walker);
  758.       *walker=(*walker)->next;
  759.       nfrags--;
  760.       FPRINTF_GC_BUG((stderr,"{Cool stack: %x->%x}",ret,ret+nbytes));
  761.       GC_BUG(memset(ret,'S',nbytes));
  762.       system_close_semaphore(&S_G_V(GC_sem)); 
  763.       return ret;
  764.     }
  765.       if ((*walker)->size<nbytes)
  766.     {
  767.       FPRINTF_GC_BUG((stderr,"[Looking at: %x->%x (%d)]",*walker,(*walker)+(*walker)->size,
  768.               (*walker)->size));      
  769.       walker = &((*walker)->next);
  770.     }
  771.       else
  772.     {
  773.       ret= ((char *)((*walker)+1))+((*walker)->size-nbytes);
  774.       (*walker)->size=(*walker)->size-nbytes;
  775.       GC_BUG(memset(ret,'S',nbytes));
  776.       FPRINTF_GC_BUG((stderr,"{Alloc stack: %x->%x}",ret,ret+nbytes));
  777.       system_close_semaphore(&S_G_V(GC_sem)); 
  778.       return ret;
  779.     }
  780.     }
  781.   fprintf(stderr,"alloc stack: stack wimped out (%d remaining --- probably)\n",free_count);
  782.   system_close_semaphore(&S_G_V(GC_sem)); 
  783.   return NULL;
  784. }
  785. #endif
  786.  
  787. #ifdef CGC
  788. void deallocate_stack(LispObject *stacktop, char *addr,int nbytes)
  789. {
  790.  /* could use gc_free(object) here? */
  791. }
  792. #else
  793. void deallocate_stack(LispObject *stacktop, char *addr,int nbytes)
  794. {
  795.   FreeList old, walker;
  796.   /* Too damm lazy */
  797.   nbytes=ROUND_ADDR(nbytes);
  798.  
  799.   
  800.   system_open_semaphore(stacktop,&S_G_V(GC_sem)); 
  801.   walker=SYSTEM_GLOBAL_VALUE(stack_chain);
  802.   FPRINTF_GC_BUG((stderr,"{dealloc: %x->%x [%d]",addr,addr+nbytes,nbytes));
  803.   while (   ((char *)walker->next) < addr
  804.      && walker->next!=NULL)
  805.     {
  806.       /* sanity check */
  807. #if 0    /* sun allocates shared memory in the wrong order */
  808.       if (walker >= walker->next)
  809.     { 
  810.       FPRINTF_GC_BUG((stderr,"Rats--- strange chain\n"));
  811.       system_lisp_exit(1);
  812.     }
  813. #endif
  814.       walker=walker->next;
  815.     }
  816.   /* 3 cases --- at the start */
  817.   if ( ((char *)(walker+1)) + walker->size == addr)
  818.     {
  819.       /* side check for end */
  820.  
  821.       if (walker->next!=NULL && addr+nbytes == (char *) walker->next)
  822.     {
  823.       walker->size = walker->size+nbytes
  824.         +sizeof(*walker)
  825.           +walker->next->size;
  826.       walker->next=walker->next->next;
  827.       free_count+=nbytes+sizeof(*walker);
  828.       nfrags--;
  829.       FPRINTF_GC_BUG((stderr,"Filler}"));
  830.     }
  831.       else    
  832.     {
  833.       walker->size=walker->size+nbytes;
  834.       free_count+=nbytes;
  835.       FPRINTF_GC_BUG((stderr,"Start}"));
  836.     }
  837.       system_close_semaphore(&S_G_V(GC_sem)); 
  838.       return;
  839.     }
  840.   /* at the end */
  841.   if ( walker->next!=NULL && addr+nbytes == (char *) walker->next)
  842.     {
  843.       old=walker->next;
  844.       walker->next=(FreeList) addr;
  845.       walker->next->size=nbytes+old->size;
  846.       walker->next->next=old->next;
  847.       free_count+=nbytes;
  848.       FPRINTF_GC_BUG((stderr,"End}"));
  849.       system_close_semaphore(&S_G_V(GC_sem)); 
  850.       return;
  851.     }
  852.   /* in the middle */
  853.   old=walker->next;      
  854.   walker->next=(FreeList) addr;
  855.   walker->next->next=old;
  856.   walker->next->size=nbytes-sizeof(*walker);
  857.   nfrags++;
  858.   free_count+=nbytes-sizeof(*walker);
  859.   FPRINTF_GC_BUG((stderr,"Middle}"));
  860.   system_close_semaphore(&S_G_V(GC_sem)); 
  861. }
  862. #endif 
  863.   
  864. int dump_obj(unsigned int *x,int s)
  865. {
  866.   int i;
  867.   
  868.   if (s>200) s=16;
  869.  
  870.   for (i=0; i<s ; i+=4)
  871.     fprintf(stderr,"0x%x: %x %x %x %x\n",
  872.         x+i,
  873.         (int)*(x+i),(int)*(x+i+1),(int)*(x+i+2),(int)*(x+i+3));
  874.   return s;
  875. }
  876.   
  877.